package com.mars.base.common.utils;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.util.WebUtils;


/**
 * Web层辅助类
 * 
 * @author yhaoquan
 * 
 */
public final class WebUtil extends WebUtils {

	private static final Logger logger = LoggerFactory.getLogger(WebUtil.class);

	private static final String ENCODING = "UTF-8";

	private WebUtil() {
	}

	/**
	 * 判断请求是否为 AJAX
	 * @param request
	 * @return
	 */
	public static boolean isAjax(HttpServletRequest request) {
		return "XMLHttpRequest".equals(request.getHeader("X-Requested-With")) ? true : false;
	}

	/**
	 * AJAX 设置 response 返回状态
	 * @param response
	 * @param status
	 * @param tip
	 */
	public static void ajaxStatus(HttpServletResponse response, int status, String tip) {
		try {
			response.setContentType("text/html;charset=" + ENCODING);
			response.setStatus(status);
			PrintWriter out = response.getWriter();
			out.print(tip);
			out.flush();
		} catch (IOException e) {
			logger.error(e.toString());
		}
	}

	/**
	 * 获取当前 URL 包含查询条件
	 * @param request
	 * @param encode
	 * @return
	 * @throws IOException
	 */
	public static String getQueryString(HttpServletRequest request, String encode) throws IOException {
		StringBuffer sb = new StringBuffer(request.getRequestURL());
		String query = request.getQueryString();
		if (query != null && query.length() > 0) {
			sb.append("?").append(query);
		}
		return URLEncoder.encode(sb.toString(), encode);
	}

	/**
	 * getRequestURL是否包含在URL之内
	 * @param request
	 * @param url
	 * @return
	 */
	public static boolean inContainURL(HttpServletRequest request, String url) {
		boolean result = false;
		if (url != null && !"".equals(url.trim())) {
			String[] urlArr = url.split(";");
			StringBuffer reqUrl = new StringBuffer(request.getRequestURL());
			for (int i = 0; i < urlArr.length; i++) {
				if (reqUrl.indexOf(urlArr[i]) > 1) {
					result = true;
					break;
				}
			}
		}
		return result;
	}

	/**
	 * URLEncoder 返回地址
	 * @param url 跳转地址
	 * @param retParam 返回地址参数名
	 * @param retUrl 返回地址
	 * @return
	 */
	public static String encodeRetURL(String url, String retParam, String retUrl) {
		return encodeRetURL(url, retParam, retUrl, null);
	}

	/**
	 * URLEncoder 返回地址
	 * @param url 跳转地址
	 * @param retParam 返回地址参数名
	 * @param retUrl 返回地址
	 * @param data 携带参数
	 * @return
	 */
	public static String encodeRetURL(String url, String retParam, String retUrl, Map<String, String> data) {
		if (url == null) {
			return null;
		}

		StringBuffer retStr = new StringBuffer(url);
		retStr.append("?");
		retStr.append(retParam);
		retStr.append("=");
		try {
			retStr.append(URLEncoder.encode(retUrl, ENCODING));
		} catch (UnsupportedEncodingException e) {
			logger.error("encodeRetURL error." + url);
			e.printStackTrace();
		}

		if (data != null) {
			for (Map.Entry<String, String> entry : data.entrySet()) {
				retStr.append("&").append(entry.getKey()).append("=").append(entry.getValue());
			}
		}

		return retStr.toString();
	}

	/**
	 * URLDecoder 解码地址
	 * @param url
	 * @return
	 */
	public static String decodeURL(String url) {
		if (url == null) {
			return null;
		}
		String retUrl = "";
		try {
			retUrl = URLDecoder.decode(url, ENCODING);
		} catch (UnsupportedEncodingException e) {
			logger.error("encodeRetURL error." + url);
			e.printStackTrace();
		}
		return retUrl;
	}
	
	/**
	 * URLEncoder 编码地址
	 * @param url
	 * @return
	 */
	public static String encodeURL(String url) {
		if (url == null) {
			return null;
		}
		String retUrl = "";
		try {
			retUrl = URLEncoder.encode(url, ENCODING);
		} catch (UnsupportedEncodingException e) {
			logger.error("encodeRetURL error." + url);
			e.printStackTrace();
		}
		return retUrl;
	}
	
	/**
	 * 编码
	 * @param content
	 * @return
	 */
	public static String encode(String content) {
		return encodeURL(content) ;
	}
	
	/**
	 * 解码
	 * @param content
	 * @return
	 */
	public static String decode(String content) {
		return decodeURL(content) ;
	}

	/**
	 * 判断是否 GET 请求
	 * @param request
	 * @return
	 */
	public static boolean isGet(HttpServletRequest request) {
		if ("GET".equalsIgnoreCase(request.getMethod())) {
			return true;
		}
		return false;
	}

	/**
	 * 判断是否 POST 请求
	 * @param request
	 * @return
	 */
	public static boolean isPost(HttpServletRequest request) {
		if ("POST".equalsIgnoreCase(request.getMethod())) {
			return true;
		}
		return false;
	}

	/**
	 * 请求重定向至地址 location
	 * @param response 请求响应
	 * @param location 重定向至地址
	 */
	public static void sendRedirect(HttpServletResponse response, String location) {
		try {
			response.sendRedirect(location);
		} catch (IOException e) {
			logger.error("sendRedirect location:" + location);
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取Request Playload 内容
	 * @param request
	 * @return Playload 内容
	 * @throws IOException
	 */
	public static String requestPlayload(HttpServletRequest request) throws IOException {
		StringBuilder stringBuilder = new StringBuilder();
		BufferedReader bufferedReader = null;
		try {
			InputStream inputStream = request.getInputStream();
			if (inputStream != null) {
				bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
				char[] charBuffer = new char[128];
				int bytesRead = -1;
				while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
					stringBuilder.append(charBuffer, 0, bytesRead);
				}
			} else {
				stringBuilder.append("");
			}
		} catch (IOException ex) {
			throw ex;
		} finally {
			if (bufferedReader != null) {
				try {
					bufferedReader.close();
				} catch (IOException ex) {
					throw ex;
				}
			}
		}
		return stringBuilder.toString();
	}

	/**
	 * 获得参数Map
	 * @param request
	 * @return
	 */
	public static final Map<String, Object> getParameterMap(HttpServletRequest request) {
		return WebUtils.getParametersStartingWith(request, null);
	}
	
	/**
	 * 获取IP地址
	 * @param request
	 * @return
	 */
	public static final String getIpAddress(HttpServletRequest request) {
		return IpHelper.getIpAddr(request);
	}

	/**
	 * 获取项目上下文路径
	 * 
	 * @param request
	 * @return
	 */
	public static final String getContextPath(HttpServletRequest request) {
		return request.getSession().getServletContext().getContextPath();
	}
	
	/**
	 * 获取上下文绝对路径
	 * @param request
	 * @param path
	 * @return
	 */
	public static final String getRealPath(HttpServletRequest request, String path) {
		try {
			return WebUtils.getRealPath(request.getServletContext(), path);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		return null;
	}
	public static final String getRealPath(HttpServletRequest request) {
		return getRealPath(request, "") ;
	}

	/**
	 * 上一次请求的地址
	 * 
	 * @param request
	 * @return
	 */
	public static String getBackURL(HttpServletRequest request) {
		if(null != request) {
			String url = request.getParameter("preRequest");
			// 使用Filter时 文件上传时 getParameter时为null 所以改成Interceptor
			if (StringUtils.isEmpty(url)) {
				url = request.getHeader("Referer");
			}
			if (!StringUtils.isEmpty(url) && (url.startsWith("http://") || url.startsWith("https://"))) {
				return url;
			}
			if (!StringUtils.isEmpty(url) && url.startsWith(request.getContextPath())) {
				url = getDomain(request) + url;
			}
			return url;
		}
		return null;
	}


	/**
	 * 获取当前访问的URL地址
	 * 
	 * @param request
	 * @param needQueryString
	 * @return
	 */
	public static String getCurrentUrl(HttpServletRequest request, boolean needQueryString) {
		try {
			String url = request.getRequestURI();
			String queryString = request.getQueryString();
			if (!StringUtils.isEmpty(queryString)) {
				queryString = "?" + queryString;
				if (queryString.startsWith("&")) {
					queryString = "?" + queryString.substring(1);
				}
			}
			if (!StringUtils.isEmpty(queryString) && needQueryString) {
				url = url + queryString;
			}
			return getDomain(request) + url;
		} catch (NullPointerException e) {
			logger.error("无法取得HttpServletRequest对象：{}", e.getMessage());
		}
		return null;
	}
	public static String getCurrentUrl(HttpServletRequest request) {
		return getCurrentUrl(request, false) ;
	}
	
	/**
	 * 获取当前访问的URI
	 * @param request
	 * @param needQueryString
	 * @return
	 */
	public static String getCurrentUri(HttpServletRequest request, boolean needQueryString) {
		try {
			String url = request.getRequestURI();
			String queryString = request.getQueryString();
			if (!StringUtils.isEmpty(queryString)) {
				queryString = "?" + queryString;
				if (queryString.startsWith("&")) {
					queryString = "?" + queryString.substring(1);
				}
			}
			if (!StringUtils.isEmpty(queryString) && needQueryString) {
				url = url + queryString;
			}
			return url;
		} catch (NullPointerException e) {
			logger.debug("无法取得HttpServletRequest对象：{}", e.getMessage());
		}
		return null;
	}
	public static String getCurrentUri(HttpServletRequest request) {
		return getCurrentUri(request, false) ;
	}

	/**
	 * 提取服务器URL地址
	 * 
	 * @param request
	 * @return
	 */
	public static String getDomain(HttpServletRequest request) {
		try {
			StringBuffer baseUrl = new StringBuffer();
			String scheme = request.getScheme();
			int port = request.getServerPort();
			
			baseUrl.append(scheme); // http, https
			baseUrl.append("://");
			baseUrl.append(request.getServerName());
			if ((scheme.equals("http") && port != 80) || (scheme.equals("https") && port != 443)) {
				baseUrl.append(':');
				baseUrl.append(request.getServerPort());
			}
			return baseUrl.toString();
		} catch (NullPointerException e) {
			logger.error("无法取得HttpServletRequest对象：{}", e.getMessage());
		}
		return null;
	}

}
